package com.anlu.base.common.security.component;

import com.anlu.base.common.core.util.SpringContextHolder;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.core.ParameterizedTypeReference;
import org.springframework.core.convert.converter.Converter;
import org.springframework.http.HttpOutputMessage;
import org.springframework.http.MediaType;
import org.springframework.http.converter.GenericHttpMessageConverter;
import org.springframework.http.converter.HttpMessageNotWritableException;
import org.springframework.http.converter.cbor.MappingJackson2CborHttpMessageConverter;
import org.springframework.security.oauth2.core.endpoint.DefaultOAuth2AccessTokenResponseMapConverter;
import org.springframework.security.oauth2.core.endpoint.OAuth2AccessTokenResponse;
import org.springframework.security.oauth2.core.http.converter.OAuth2AccessTokenResponseHttpMessageConverter;

import java.util.Map;
/*
   扩展原生的实现，支持 Long2String
   OAuth2AccessTokenResponseHttpMessageConverter 是一个消息转换器，
   通常在使用 OAuth 2.0 协议的应用程序中使用，特别是在处理 HTTP 请求和响应时发挥作用
 */
public class PigCustomOAuth2AccessTokenResponseHttpMessageConverter extends OAuth2AccessTokenResponseHttpMessageConverter {

    /**
     * ParameterizedTypeReference
     * 是一个在 Java 中用于处理参数化类型（Parameterized Types）的工具类，特别是在使用 Java 的泛型和反射机制时。
     * 它允许在运行时保留泛型类型信息，这在一些需要对泛型进行复杂操作的场景中非常有用。
     */
    private static final ParameterizedTypeReference<Map<String, Object>> STRING_OBJECT_MAP = new ParameterizedTypeReference<Map<String, Object>>() {
    };

    private Converter<OAuth2AccessTokenResponse, Map<String, Object>> accessTokenResponseParametersConverter = new DefaultOAuth2AccessTokenResponseMapConverter();

    /**
     * OAuth2AccessTokenResponse 是一个简单的 Java 类，用来存储 OAuth 2.0 访问令牌响应的信息，
     * 包括 accessToken、tokenType、expiresIn、refreshToken 和 scope 等。
     * @param tokenResponse
     * @param outputMessage
     * @throws HttpMessageNotWritableException
     */
    @Override
    protected void writeInternal(OAuth2AccessTokenResponse tokenResponse,HttpOutputMessage outputMessage)throws HttpMessageNotWritableException {

        try {
            Map<String,Object> tokenResponseParameters = this.accessTokenResponseParametersConverter.convert(tokenResponse);
            ObjectMapper objectMapper = SpringContextHolder.getBean(ObjectMapper.class);
            GenericHttpMessageConverter<Object> jsonMessageConverter = new MappingJackson2CborHttpMessageConverter(objectMapper);
            jsonMessageConverter.write(tokenResponseParameters, STRING_OBJECT_MAP.getType(), MediaType.APPLICATION_JSON,
                    outputMessage);
        } catch (Exception ex) {
            throw new HttpMessageNotWritableException(
                    "An error occurred writing the OAuth 2.0 Access Token Response: " + ex.getMessage(), ex);
        }

    }

}
